package com.dims_hsrc.web.controller.data;

import java.util.List;
import java.util.Map;

import com.dims_hsrc.data.domain.DataFunctionMapping;
import com.dims_hsrc.data.domain.DataFunctionMappingResult;
import com.dims_hsrc.data.service.IDataFunctionMappingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RequestBody;
import com.dims_hsrc.common.annotation.Log;
import com.dims_hsrc.common.enums.BusinessType;
import com.dims_hsrc.common.core.controller.BaseController;
import com.dims_hsrc.common.core.domain.AjaxResult;
import com.dims_hsrc.common.utils.poi.ExcelUtil;
import com.dims_hsrc.common.core.page.TableDataInfo;
import org.springframework.http.ResponseEntity;


/**
 * 函数映射配置Controller
 * 
 * @author 赵浩然
 * @date 2023-07-15
 */
@Controller
@RequestMapping("/data/function_mapping")
public class DataFunctionMappingController extends BaseController
{
    private String prefix = "data/function_mapping";

    @Autowired
    private IDataFunctionMappingService dataFunctionMappingService;

    @GetMapping()
    public String functionMapping()
    {
        return prefix + "/function_mapping";
    }

    /**
     * 查询函数映射配置列表
     */
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(DataFunctionMapping dataFunctionMapping)
    {
        startPage();
        List<DataFunctionMapping> list = dataFunctionMappingService.selectDataFunctionMappingList(dataFunctionMapping);
        return getDataTable(list);
    }

    /**
     * 导出函数映射配置列表
     */
    @Log(title = "函数映射配置", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(DataFunctionMapping dataFunctionMapping)
    {
        List<DataFunctionMapping> list = dataFunctionMappingService.selectDataFunctionMappingList(dataFunctionMapping);
        ExcelUtil<DataFunctionMapping> util = new ExcelUtil<DataFunctionMapping>(DataFunctionMapping.class);
        return util.exportExcel(list, "函数映射配置数据");
    }

    /**
     * 新增函数映射配置
     */
    @GetMapping("/add")
    public String add()
    {
        return prefix + "/add";
    }

    /**
     * 新增保存函数映射配置
     */
    @Log(title = "函数映射配置", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @ResponseBody
    public AjaxResult addSave(DataFunctionMapping dataFunctionMapping)
    {
        return toAjax(dataFunctionMappingService.insertDataFunctionMapping(dataFunctionMapping));
    }

    /**
     * 修改函数映射配置
     */
    @GetMapping("/edit/{id}")
    public String edit(@PathVariable("id") String id, ModelMap mmap)
    {
        DataFunctionMapping dataFunctionMapping = dataFunctionMappingService.selectDataFunctionMappingById(id);
        mmap.put("dataFunctionMapping", dataFunctionMapping);
        return prefix + "/edit";
    }

    /**
     * 修改保存函数映射配置
     */
    @Log(title = "函数映射配置", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult editSave(DataFunctionMapping dataFunctionMapping)
    {
        return toAjax(dataFunctionMappingService.updateDataFunctionMapping(dataFunctionMapping));
    }

    /**
     * 删除函数映射配置
     */
    @Log(title = "函数映射配置", businessType = BusinessType.DELETE)
    @PostMapping( "/remove")
    @ResponseBody
    public AjaxResult remove(String ids)
    {
        return toAjax(dataFunctionMappingService.deleteDataFunctionMappingByIds(ids.split(",")));
    }
    
    /**
     * 根据需求ID查询映射
     */
    @PostMapping("/bySdid/{sdid}")
    @ResponseBody
    public AjaxResult getByDemandId(@PathVariable("sdid") String sdid)
    {
        List<DataFunctionMapping> mappings = dataFunctionMappingService.selectDataFunctionMappingBySdid(sdid);
        return AjaxResult.success(mappings);
    }
    
    /**
     * 根据指标ID查询映射
     */
    @PostMapping("/bySiid/{siid}")
    @ResponseBody
    public AjaxResult getByIndicatorId(@PathVariable("siid") String siid)
    {
        List<DataFunctionMapping> mappings = dataFunctionMappingService.selectDataFunctionMappingBySiid(siid);
        return AjaxResult.success(mappings);
    }
    
    /**
     * 根据结构ID查询映射
     */
    @PostMapping("/bySid/{sid}")
    @ResponseBody
    public AjaxResult getByStructId(@PathVariable("sid") String sid)
    {
        List<DataFunctionMapping> mappings = dataFunctionMappingService.selectDataFunctionMappingBySid(sid);
        return AjaxResult.success(mappings);
    }
    
    /**
     * 检查映射是否存在
     */
    @PostMapping("/checkExists")
    @ResponseBody
    public AjaxResult checkMappingExists(String sdid, String siid)
    {
        DataFunctionMapping mapping = dataFunctionMappingService.selectDataFunctionMappingBySdidAndSiid(sdid, siid);
        return AjaxResult.success(mapping != null);
    }
    
    /**
     * 计算公式结果
     */
    @PostMapping("/calculate/{id}")
    @ResponseBody
    public AjaxResult calculate(@PathVariable("id") String id, @RequestBody Map<String, Double> variables)
    {
        Map<String, Object> result = dataFunctionMappingService.calculateFormula(id, variables);
        return AjaxResult.success(result);
    }
    
    /**
     * 测试公式
     */
    @PostMapping("/testFormula")
    @ResponseBody
    public AjaxResult testFormula(@RequestBody Map<String, Object> params)
    {
        String formula = (String) params.get("formula");
        @SuppressWarnings("unchecked")
        Map<String, Double> variables = (Map<String, Double>) params.get("variables");
        
        double result = dataFunctionMappingService.testFormula(formula, variables);
        return AjaxResult.success("计算结果", result);
    }
    
    /**
     * 检查数字类型需求是否已被函数映射
     */
    @PostMapping("/checkDemandMapped/{sdid}")
    @ResponseBody
    public AjaxResult checkDemandMapped(@PathVariable("sdid") String sdid)
    {
        int count = dataFunctionMappingService.checkDemandMapped(sdid);
        return AjaxResult.success(count > 0);
    }

    /**
     * 检查数字类型技术指标是否已被函数映射
     */
    @PostMapping("/checkIndicatorMapped/{siid}")
    @ResponseBody
    public AjaxResult checkIndicatorMapped(@PathVariable("siid") String siid)
    {
        int count = dataFunctionMappingService.checkIndicatorMapped(siid);
        return AjaxResult.success(count > 0);
    }

    /**
     * 根据结构ID查询所有已映射的数字类型需求和技术指标
     */
    @PostMapping("/numTypeMappings/{sid}")
    @ResponseBody
    public AjaxResult getNumTypeMappings(@PathVariable("sid") String sid)
    {
        List<DataFunctionMapping> mappings = dataFunctionMappingService.getNumTypeMappingsBySid(sid);
        return AjaxResult.success(mappings);
    }

    /**
     * 批量新增函数映射配置
     */
    @Log(title = "函数映射配置", businessType = BusinessType.INSERT)
    @PostMapping("/batchAdd")
    @ResponseBody
    public AjaxResult batchAddSave(@RequestBody List<DataFunctionMapping> mappingList)
    {
        return toAjax(dataFunctionMappingService.batchInsertDataFunctionMapping(mappingList));
    }
    
    /**
     * 根据结构ID获取函数映射结果（包含需求和技术指标详细信息）
     */
    @PostMapping("/resultBySid/{sid}")
    @ResponseBody
    public AjaxResult getFunctionMappingResultBySid(@PathVariable("sid") String sid)
    {
        List<DataFunctionMappingResult> results = dataFunctionMappingService.getFunctionMappingResultBySid(sid);
        return AjaxResult.success(results);
    }
    
    /**
     * 根据ID获取函数映射详细结果
     */
    @PostMapping("/mappingResult/{id}")
    @ResponseBody
    public AjaxResult getFunctionMappingResultById(@PathVariable("id") String id)
    {
        DataFunctionMappingResult result = dataFunctionMappingService.getFunctionMappingResultById(id);
        return AjaxResult.success(result);
    }
    
    /**
     * 检查某个需求和技术指标的组合是否已经存在函数映射
     */
    @PostMapping("/checkMappingExists")
    @ResponseBody
    public AjaxResult checkFunctionMappingExists(String sid, String sdid, String siid)
    {
        boolean exists = dataFunctionMappingService.checkFunctionMappingExists(sid, sdid, siid);
        return AjaxResult.success(exists);
    }

    /**
     * 根据技术指标ID删除所有函数映射
     */
    @Log(title = "函数映射配置", businessType = BusinessType.DELETE)
    @PostMapping("/removeBySiid/{siid}")
    @ResponseBody
    public AjaxResult removeBySiid(@PathVariable("siid") String siid)
    {
        return toAjax(dataFunctionMappingService.deleteDataFunctionMappingBySiid(siid));
    }

    /**
     * 根据多个技术指标ID批量删除函数映射
     */
    @Log(title = "函数映射配置", businessType = BusinessType.DELETE)
    @PostMapping("/removeBySiids")
    @ResponseBody
    public AjaxResult removeBySiids(String siids)
    {
        return toAjax(dataFunctionMappingService.deleteDataFunctionMappingBySiids(siids.split(",")));
    }

    /**
     * 根据计数值查询函数映射
     */
    @PostMapping("/byCnt/{cnt}")
    @ResponseBody
    public AjaxResult getMappingsByCount(@PathVariable("cnt") Integer cnt)
    {
        List<DataFunctionMapping> mappings = dataFunctionMappingService.selectDataFunctionMappingByCnt(cnt);
        return AjaxResult.success(mappings);
    }
    
    /**
     * 根据计数阈值查询函数映射
     */
    @PostMapping("/byThreshold/{threshold}")
    @ResponseBody
    public AjaxResult getMappingsAboveThreshold(@PathVariable("threshold") Integer threshold)
    {
        List<DataFunctionMapping> mappings = dataFunctionMappingService.selectDataFunctionMappingByCntGreaterThan(threshold);
        return AjaxResult.success(mappings);
    }
    
    /**
     * 增加指定映射的计数值
     */
    @Log(title = "函数映射计数", businessType = BusinessType.UPDATE)
    @PostMapping("/incrementCnt/{id}")
    @ResponseBody
    public AjaxResult incrementMappingCount(@PathVariable("id") String id)
    {
        return toAjax(dataFunctionMappingService.incrementMappingCnt(id));
    }
    
    /**
     * 设置指定映射的计数值
     */
    @Log(title = "函数映射计数", businessType = BusinessType.UPDATE)
    @PostMapping("/updateCnt/{id}/{cnt}")
    @ResponseBody
    public AjaxResult updateMappingCount(@PathVariable("id") String id, @PathVariable("cnt") Integer cnt)
    {
        return toAjax(dataFunctionMappingService.updateMappingCnt(id, cnt));
    }
    
    /**
     * 重置所有映射的计数值
     */
    @Log(title = "函数映射计数", businessType = BusinessType.UPDATE)
    @PostMapping("/resetAllCnt")
    @ResponseBody
    public AjaxResult resetAllMappingCounts()
    {
        return toAjax(dataFunctionMappingService.resetAllMappingCnt());
    }

} 